﻿using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using Quartz.Util;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;

namespace Coldairarrow.Business.PB
{
    public partial class PB_MaterialTypeBusiness : BaseBusiness<PB_MaterialType>, IPB_MaterialTypeBusiness, ITransientDependency
    {
        public PB_MaterialTypeBusiness(IDbAccessor db)
            : base(db)
        {
        }

        #region 外部接口

        public async Task<PageResult<PB_MaterialType>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<PB_MaterialType>();
            var search = input.Search;

            //筛选
            if (!search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<PB_MaterialType, bool>(
                    ParsingConfig.Default, false, $@"Code.Contains(@0) or Name.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<PB_MaterialType> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public List<tmpMaterialTypeDTO> GetTheDataByCode(List<tmpMaterialTypeDTO> list)
        {
            string where = "1=1 ";
            foreach (var item in list)
            {
                where += "or Code='" + item.Code + "' ";
            }
            DataTable dt = Db.GetDataTableWithSql("select Id,Code from PB_MaterialType where " + where, null);
            if (dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    foreach (var item in list)
                    {
                        string _tmp = dt.Rows[i][1].ToString();
                        if (item.Code.Equals(_tmp))
                        {
                            item.Id = dt.Rows[i][0].ToString();
                            continue;
                        }
                    }
                }
            }
            return list;
        }

        public List<tmpUnitGroupDTO> GetTheDataByName(List<tmpUnitGroupDTO> list)
        {
            string where = "1=1 ";
            foreach (var item in list)
            {
                where += "or Name='" + item.Name + "' ";
            }
            DataTable dt = Db.GetDataTableWithSql("select Id,Name from Base_UnitGroup where " + where, null);
            if (dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    foreach (var item in list)
                    {
                        string _tmp = dt.Rows[i][1].ToString();
                        if (item.Name.Equals(_tmp))
                        {
                            item.Id = dt.Rows[i][0].ToString();
                            string subwhere = "GroupId='" + dt.Rows[i][0].ToString() + "'";
                            DataTable dtu = Db.GetDataTableWithSql("select Id,Name from Base_UnitItems where " + subwhere, null);
                            foreach (var subitem in item.Units)
                            {
                                subitem.Id = "";
                                for (int j = 0; j < dtu.Rows.Count; j++)
                                {
                                    string _name = dtu.Rows[j][1].ToString();
                                    if (subitem.Name.Equals(_name))
                                    {
                                        subitem.Id = dtu.Rows[j][0].ToString();
                                    }
                                }

                            }
                        }
                    }
                }
            }
            return list;
        }

        [DataAddLog(UserLogType.物料类型, "Code", "物料类型")]
        [DataRepeatValidate(new string[] { "Code", "Name" }, new string[] { "编号", "名称" })]
        public async Task AddDataAsync(PB_MaterialType data)
        {
            await SetPathAsync(data);
            await InsertAsync(data);
        }

        [DataEditLog(UserLogType.物料类型, "Code", "物料类型")]
        [DataRepeatValidate(new string[] { "Code", "Name" }, new string[] { "编号", "名称" })]
        public async Task UpdateDataAsync(PB_MaterialType data)
        {
            await SetPathAsync(data);
            await ModifyRefDataAsync(data);
            await UpdateAsync(data);
        }

        [DataDeleteLog(UserLogType.物料类型, "Code", "物料类型")]
        public async Task DeleteDataAsync(List<string> ids)
        {
            if (await GetIQueryable().AnyAsync(x => ids.Contains(x.ParentId)))
                throw new BusException("禁止删除！请先删除所有子级！");
            List<PB_MaterialType> listdata = await Db.GetIQueryable<PB_MaterialType>().ToListAsync();
            List<string> liststr = new List<string>();
            foreach (var item in ids)
            {
                liststr.Add(item);
                var itemlist = listdata.Where(x => x.ParentId == item).ToList();
                if (itemlist.Count > 0)
                {
                    GetmaterialtypeItem(item, liststr, itemlist, listdata);
                }
                string sqlmain = @"select * from PB_Material where MaterialTypeId='" + item + "'";
                var atAllData = await Db.GetListBySqlAsync<PB_Material>(sqlmain);
                if (atAllData.Count > 0)
                {
                    throw new BusException("该分类已经被引用禁止删除");
                }
            }
            await DeleteAsync(liststr);
        }

        private List<string> GetmaterialtypeItem(string id, List<string> liststr, List<PB_MaterialType> itemlist, List<PB_MaterialType> listdata)
        {
            foreach (var item in itemlist)
            {
                liststr.Add(item.Id);
                var itemsdata = listdata.Where(x => x.ParentId == item.Id).ToList();
                if (itemsdata.Count > 0)
                {
                    GetmaterialtypeItem(item.Id, liststr, itemsdata, listdata);
                }
            }
            return liststr;
        }

        public async Task AddDataExlAsync(List<PB_MaterialType> list)
        {
            await InsertAsync(list);

        }

        public IQueryable<T> GetQueryable<T>() where T : class, new()
        {
            return Db.GetIQueryable<T>();
        }
        public async Task<List<PB_MaterialTypeTreeDTO>> GetTreeDataListAsync(PB_MaterialTypeTreeInputDTO input)
        {
            var where = LinqHelper.True<PB_MaterialType>();
            if (!input.parentId.IsNullOrEmpty())
                where = where.And(x => x.ParentId == input.parentId);

            var list = await GetIQueryable().Where(where).ToListAsync();
            var treeList = list
                .Select(x => new PB_MaterialTypeTreeDTO
                {
                    Id = x.Id,
                    ParentId = x.ParentId,
                    Text = x.Name,
                    Value = x.Id,
                    Code = x.Code
                }).ToList();
            return TreeHelper.BuildTree(treeList);

        }
        public async Task<List<PB_MaterialTypeTreeDTO>> GetTreeDataListAsyncs(PB_MaterialTypeTreeInputDTO input)
        {
            var where = LinqHelper.True<PB_MaterialType>();
            if (!input.parentId.IsNullOrEmpty())
                where = where.And(x => x.ParentId == input.parentId);

            var list = await GetIQueryable().Where(where).ToListAsync();
            var listdata = await GetIQueryable().ToListAsync();
            var treeList = list
                .Select(x => new PB_MaterialTypeTreeDTO
                {
                    Id = x.Id,
                    ParentId = x.ParentId,
                    Text = x.Name,
                    Value = x.Id,
                    Code = x.Code,
                    Countnum = listdata.Where(w => w.ParentId == x.Id).Count()
                }).ToList();
            return treeList;
            //return TreeHelper.BuildTree(treeList);
            //return TreeHelper.GetChildren(treeList, treeList.Where(x => x.ParentId == input.parentId).FirstOrDefault(), false);

        }

        public async Task<List<PB_MaterialTypeTreeDTO>> GetTreeDataLists(PB_MaterialTypeTreeInputDTO input)
        {
            var where = LinqHelper.True<PB_MaterialType>();
            where = where.And(x => x.ParentId == null);

            var list = await GetIQueryable().Where(where).ToListAsync();
            var listdata = await GetIQueryable().ToListAsync();
            var treeList = list
                .Select(x => new PB_MaterialTypeTreeDTO
                {
                    Id = x.Id,
                    ParentId = x.ParentId,
                    Text = x.Name,
                    Value = x.Id,
                    Code = x.Code,
                    Countnum = listdata.Where(w => w.ParentId == x.Id).Count()
                }).ToList();
            return treeList;
            //return TreeHelper.BuildTree(treeList);
        }

        /// <summary>
        /// 获取物料分类
        /// </summary>
        /// <param name="ParentId">父节点Id</param>
        /// <returns></returns>

        public async Task<List<MaterialType>> GetMaterialTypeListAsync(string ParentId)
        {
            List<PB_MaterialType> listdata = new List<PB_MaterialType>();
            if (ParentId.IsNullOrEmpty())
            {
                listdata = await Db.GetIQueryable<PB_MaterialType>().Where(x => x.ParentId == null).ToListAsync();
            }
            else
            {
                listdata = await Db.GetIQueryable<PB_MaterialType>().Where(x => x.ParentId == ParentId).ToListAsync();
            }
            List<MaterialType> typelist = new List<MaterialType>();
            foreach (var item in listdata)
            {
                var list = await Db.GetIQueryable<PB_MaterialType>().Where(x => x.ParentId == item.Id).ToListAsync();

                MaterialType typedata = new MaterialType();
                typedata.Id = item.Id;
                typedata.title = item.Name;
                typedata.value = item.Id;
                typedata.ParentId = item.ParentId;
                typedata.isLeaf = list.Count > 0 ? false : true;
                typedata.Code = item.Code;
                typedata.Remarks = item.Remarks;
                typelist.Add(typedata);
            }
            return typelist;
        }


        #endregion

        #region 私有成员

        #endregion
    }
}